package org.ryan.timedstart;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TimePicker;
import android.widget.Toast;

public class ConfigActivity extends Activity {

	public static final String ACTION_BOOT_INIT = "org.ryan.BOOT_INIT";

	public static final String PREF_NAME = "alarm_list";
	public static final String PREF_KEY = "alarm_list";

	private TimePicker time;
	private Button bSetAlarm;
	private ListView lAlarms;
	private ArrayAdapter<String> la;

	/**
	 * List of times alarms are scheduled
	 */
	private ArrayList<String> alarms = new ArrayList<String>();
	/**
	 * List of PendingIntent that are used to create / cancel alarms
	 */
	private ArrayList<PendingIntent> pis = new ArrayList<PendingIntent>();

	private OnClickListener btnClickListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			int h = time.getCurrentHour();
			int m = time.getCurrentMinute();
			// la.add(String.format("%d:%02d", h, m));

			Calendar now = Calendar.getInstance();
			Calendar next = Calendar.getInstance();
			if (now.get(Calendar.HOUR_OF_DAY) > h
					|| (now.get(Calendar.HOUR_OF_DAY) == h && now
							.get(Calendar.MINUTE) > m)) {
				next.add(Calendar.DATE, 1);
			}
			next.set(Calendar.HOUR_OF_DAY, h);
			next.set(Calendar.MINUTE, m);
			next.set(Calendar.SECOND, 0);

			ConfigActivity.this.setAlarm(BootUpReceiver.ALARM_REPEAT,
					next.getTime());
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		loadAlarmList();

		Intent i = getIntent();
		if (ACTION_BOOT_INIT.equals(i.getAction())) {
			String msg = String.format("BOOT_INIT: %d tasks", alarms.size());
			Toast.makeText(ConfigActivity.this,
					msg,
					Toast.LENGTH_LONG).show();
			Log.e("XXX", msg);
			if (alarms.size() > 0) {
				DateFormat df = SimpleDateFormat.getDateTimeInstance();
				AlarmManager am = (AlarmManager) this
						.getSystemService(Context.ALARM_SERVICE);
				for (String line : alarms) {
					try {
						setOneAlarm(BootUpReceiver.ALARM_REPEAT,
								df.parse(line), am);
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				finish();
				return;
			}
		}

		setContentView(R.layout.activity_config);

		time = (TimePicker) findViewById(R.id.timepicker);
		time.setIs24HourView(true);
		bSetAlarm = (Button) findViewById(R.id.btn_set_alarm);
		lAlarms = (ListView) findViewById(R.id.list_alarms);
		la = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, alarms);
		lAlarms.setAdapter(la);

		bSetAlarm.setOnClickListener(btnClickListener);

		if (savedInstanceState != null) {
			pis = savedInstanceState.getParcelableArrayList("pis");
		}
		if (pis == null) {
			pis = new ArrayList<PendingIntent>();
		}

	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putParcelableArrayList("pis", pis);
		saveAlarmList();
		super.onSaveInstanceState(outState);
	}

	private void setAlarm(long repeat, Date... date) {

		AlarmManager am = (AlarmManager) this
				.getSystemService(Context.ALARM_SERVICE);
		DateFormat df = SimpleDateFormat.getDateTimeInstance();

		for (Date d : date) {
			setOneAlarm(repeat, d, am);
			String ds = df.format(d.getTime());
			if (la != null) {
				la.add(ds);
			} else {
				alarms.add(ds);
			}
		}
	}

	private void setOneAlarm(long repeat, Date date, AlarmManager am) {
		Intent i = new Intent(BootUpReceiver.ACTION);
		i.setData(Uri.parse("wakeup://" + date.toGMTString().replace(' ', '_')));
		PendingIntent pintent = PendingIntent.getBroadcast(this, 0, i, 0);
		pis.add(pintent);
		am.setInexactRepeating(AlarmManager.RTC_WAKEUP, date.getTime(), repeat,
				pintent);

	}

	private void cancelAlarm() {
		for (PendingIntent p : pis) {
			p.cancel();
		}
		pis.clear();
		la.clear();
	}

	/**
	 * Save alarm time list to SharedPreferences
	 */
	@SuppressLint("WorldWriteableFiles")
	private void saveAlarmList() {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < alarms.size(); ++i) {
			String line = alarms.get(i);
			DateFormat df = SimpleDateFormat.getDateTimeInstance();
			Date date;
			try {
				date = df.parse(line);
				sb.append(date.getTime()).append(' ');
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		SharedPreferences pref = this.getSharedPreferences(PREF_NAME,
				Context.MODE_WORLD_WRITEABLE);
		Editor edit = pref.edit();
		edit.putString(PREF_KEY, sb.toString().trim());
		edit.commit();
	}

	private void loadAlarmList() {
		Calendar today = Calendar.getInstance();
		DateFormat df = SimpleDateFormat.getDateTimeInstance();

		SharedPreferences pref = this.getSharedPreferences(PREF_NAME, 0);
		if (pref.contains(PREF_KEY)) {
			String allstr = pref.getString(PREF_KEY, "");
			String[] parts = allstr.split(" ");
			ArrayList<Date> ts = new ArrayList<Date>();
			for (String s : parts) {
				try {
					long mils = Long.parseLong(s);
					Calendar c = Calendar.getInstance();
					c.setTimeInMillis(mils);
					c.set(today.get(Calendar.YEAR), today.get(Calendar.MONTH),
							today.get(Calendar.DAY_OF_MONTH));
					if (c.before(today)) {
						c.add(Calendar.DATE, 1);
					}
					Date t = c.getTime();
					alarms.add(df.format(t));
					ts.add(t);
				} catch (NumberFormatException e) {
					// ignore
				}
			}
			setAlarm(BootUpReceiver.ALARM_REPEAT,
					ts.toArray(new Date[ts.size()]));
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_config, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		cancelAlarm();
		return true;
	}
}
